class Person {
  name: string;
  age: number;
  addr: string;
  static count: number = 10;
  constructor(_name: string, _age: number, _addr: string) {
    this.name = _name;
    this.age = _age;
    this.addr = _addr;
  }

  doEat(who: string, where: string) {
    console.log(`who:${who}, where: ${where}`);
  }

  doStop() {}
}

class StringUtil {
  static trimSpace(str: string) {
    return str.replace(/\s+/g, "");
  }
}

// 每次获取对象属性，都会开辟一个新的空间
const dataProp1 = Object.getOwnPropertyDescriptor(Person.prototype, "doEat");
// dataProp1?.value();
// 保存原有的方法
const targetMethod = dataProp1!.value;
// 指向新的方法
dataProp1!.value = function (...args: any[]) {
  args = args.map((arg) => {
    if (typeof arg === "string") {
      return StringUtil.trimSpace(arg);
    } else {
      return arg;
    }
  });
  console.log("前置拦截");
  targetMethod.apply(this, args);
  console.log("后置拦截");
};

// 不能这样调用，真正项目中需要通过具体对象，具体类调用
// dataProp1?.value("zs", "江西");
Object.defineProperty(Person.prototype, "doEat", dataProp1!);
let p = new Person("peter", 21, "江西");
p.doEat("z s", "上   饶");

const dataProp2 = Object.getOwnPropertyDescriptor(Person.prototype, "doEat");

export {};
